package edu.pitt.cs3530.scripts;

import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileReader;
import java.io.FileWriter;
import java.io.IOException;
import java.sql.Connection;
import java.util.LinkedList;
import java.util.List;
import java.util.StringTokenizer;
import java.util.Vector;

public class WriteQosGraph {
	
	private static class QosSecond {
		private double madePercent;
		private double missedPercent;
		private double qos;
		private QosSecond(double madePercent, double missedPercent, double qos) {
			this.madePercent = madePercent;
			this.missedPercent = missedPercent;
			this.qos = qos;
		}
	}
	
	public static void main(String args[]) {
		File fileArg = new File(args[0]);
		Connection conn = null;
		String outputDirectory = args[1];
		File outputDirFile = new File(outputDirectory);
		if (!outputDirFile.exists()) {
			outputDirFile.mkdirs();
		}
		long deadline = Long.parseLong(args[2]);
		List<File> fileList = new LinkedList<File>();
		if (fileArg.isDirectory()) {
			for (File file : fileArg.listFiles()) {
				fileList.add(file);
			}
		} else {
			fileList.add(fileArg);
		}
		for (File file : fileList) {
			System.out.println("Processing: " + file.getName());
			writeQos(file, outputDirectory, deadline);
			System.out.println("Finished: " + file.getName());
		}
	}
	
	private static void writeQos(File file, String outputDirectory, long deadline) {
		long currentSecond = -1;
		double currentQos = 0.0;
		long currentSecondMade = 0;
		long currentSecondMissed = 0;
		try {
			List<QosSecond> qos = new LinkedList<QosSecond>();
			String prefix = outputDirectory + "/" + file.getName();
			BufferedReader reader = new BufferedReader(new FileReader(file));
			BufferedWriter qosToWrite = new BufferedWriter(new FileWriter(prefix + "-qos"));
			BufferedWriter madeToWrite = new BufferedWriter(new FileWriter(prefix + "-made"));
			BufferedWriter missedToWrite = new BufferedWriter(new FileWriter(prefix + "-missed"));
			BufferedWriter throughputToWrite = new BufferedWriter(new FileWriter(prefix + "-throughput"));
			while (reader.ready()) {
				String line = reader.readLine();
				StringTokenizer tok = new StringTokenizer(line, "-");
				tok.nextToken();
				long firstSec = Long.parseLong(tok.nextToken());
				long firstUsec = Long.parseLong(tok.nextToken());
				long secondSec = Long.parseLong(tok.nextToken());
				long secondUsec = Long.parseLong(tok.nextToken());
				if (firstSec != currentSecond) {
					double total = currentSecondMade + currentSecondMissed;
					double madePercent = (double) currentSecondMade / total;
					double missedPercent = (double) currentSecondMissed / total;
					int throughput = (int) total;
					qos.add(new QosSecond(madePercent, missedPercent, currentQos / total));
					if (qos.size() > 20) {
						qos.remove(0);
					}
					QosSecond second = WriteQosGraph.getAverageQos(qos);
					madeToWrite.write(currentSecond + ":" + second.madePercent + "\r\n");
					missedToWrite.write(currentSecond + ":" + second.missedPercent + "\r\n");
					qosToWrite.write(currentSecond + ":" + second.qos + "\r\n");
					throughputToWrite.write(currentSecond + ":" + throughput + "\r\n");
					currentSecond = firstSec;
					currentQos = 0;
					currentSecondMade = 0;
					currentSecondMissed = 0;
				}
				double fin = ((secondSec - firstSec) * 1000000.0 + (secondUsec - firstUsec)) / 1000.0;
				if (fin > deadline) {
					currentSecondMissed++;
				} else {
					currentSecondMade++;
				}
				currentQos += (double) fin / (double) deadline;
			}
			reader.close();
			qosToWrite.flush();
			qosToWrite.close();
			madeToWrite.flush();
			madeToWrite.close();
			missedToWrite.flush();
			missedToWrite.close();
			throughputToWrite.flush();
			throughputToWrite.close();
			
		} catch (FileNotFoundException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		} catch (IOException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
	}
	
	private static QosSecond getAverageQos(List<QosSecond> list) {
		QosSecond retval = null;
		double totalMade = 0.0;
		double totalMissed = 0.0;
		double totalQos = 0.0;
		for (QosSecond qs : list) {
			totalMade += qs.madePercent;
			totalMissed += qs.missedPercent;
			totalQos += qs.qos;
		}
		retval = new QosSecond(totalMade / (double) list.size(), totalMissed / (double) list.size(), totalQos / (double) list.size());
		return retval;
	}
}
